#ifndef __PACHIRA_PNR_API_H_
#define __PACHIRA_PNR_API_H_

//#define LOW_QUALITY_NOISE  0x1000
#define HIGH_QUALITY_NOISE 0x2000
//#define LOW_QUALITY_ECHO   0x0100
#define HIGH_QUALITY_ECHO  0x0200
//#define LOW_QUALITY_VOICE  0x0010
#define HIGH_QUALITY_VOICE 0x0020
#define LOW_QUALITY_NOISE_ECHO 0x2200
#define LOW_QUALITY_ECHO_HIGH_VOICE 0x0220

#define ENABLE_VEC_BIN 0  //是否启用ECNR参数化的功能。0为不启用，1为启用
#define ENABLE_ONLY_ONE_VEC 0  //要启用这个，必须先启用ENABLE_VEC_BIN。启用之后，只加载外部的唯一vec文件

typedef enum {
    PNR_API_CODE_OK = 0,
    PNR_API_CODE_INVALID_SAMPLE_RATE = -1,
    PNR_API_CODE_INVALID_QBIT = -2, 
    PNR_API_CODE_INVALID_PARAM = -3,
    PNR_API_CODE_INVALID_WORKMODE = -4,
    PNR_API_CODE_UNSUPPORT_OPERATION = -5,
    PNR_API_CODE_NO_MEMORY = -6,
    PNR_API_CODE_INVALID_ENGINE = -7
}PNR_API_CODE;

typedef struct aibs_pnr_data_st{
    char *input; //表示多通道的数据，数据通道数量由CHANNEL_NUM指定。
    char *output; //输出数据，声道数由工作模式和start_pnr_engine中的output_channel_mask 和 synth_method确定，不同音区数据以非交织方式存储。
}*aibs_pnr_data_t;

typedef struct pnr_config_st {
    char type[32]; // 当前设备标识
    int mic_num;  // 用于指定MIC的数量
    int mic_distance;  // 用于指定MIC的距离
    int channel_num; // 用于指定输入数据的通道数量(含mic和reference)。
}*pnr_config_t;

typedef enum{
    mode_VR = 0,  
    mode_BT,     
    mode_CARPLAY,
    mode_WECHAT,  
    mode_CARLINK,
    mode_HICAR,
    mode_CARLINK_VR,
    mode_HICAR_VR,
    mode_WECHAT_VR,
    mode_COMMON,
    mode_DOWNLINK,
}PNR_WORK_MODE;

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief create_pnr_engine
 * @param pnr_config: config file
 * @return if success, will return resource pointer, or else return NULL;
 **/
void* create_pnr_engine(struct pnr_config_st *pnr_config);

/**
 * @brief create_linein_pnr_engine
 * @param pnr_config: config file
 * @return if success, will return resource pointer, or else return NULL;
 **/
void* create_linein_pnr_engine(struct pnr_config_st *pnr_config);

/**
 * @brief start pnr engine
 * @param engine:    pnr instance
 * @param input_sample_rate:    input audio's sample rate
 * @param output_sample_rate:    output audio's sample rate
 * @param format:    audio's format, egs 16bit
 * @param output_channel_mask: output index channel voice, like 1 is equal to the first channel voice; and 3 is equal to the first and second channel voice
 * @param synth_method: the method of the output audio 
 * @return if success, return 0, or else return err code
 **/
int start_pnr_engine(void* engine, int input_sample_rate, int output_sample_rate, int format, int output_channel_mask, int synth_method);

/**
 * @brief start linein pnr engine
 * @param engine:    pnr instance
 * @param input_sample_rate:    input audio's sample rate
 * @param output_sample_rate:    output audio's sample rate
 * @param format:    audio's format, egs 16bit
 * @param output_channel_mask: output index channel voice, like 1 is equal to the first channel voice; and 3 is equal to the first and second channel voice
 * @param synth_method: the method of the output audio 
 * @return if success, return 0, or else return err code
 **/
int start_linein_pnr_engine(void* engine, int input_sample_rate, int output_sample_rate, int format, int output_channel_mask, int synth_method);

/**
 * @brief process data in frame, at the same time, the preprocess is completed.
 * @param engine:    instance that create by create_aibs_engine
 * @param data:        contain input and output data
 * @param tsize:       the time length of the input data 
 * @param timestamp:   the time stampl of the input data
 * @return if success, return 0, or if failed, return err code;
 **/
int process_pnr_data(void *engine, aibs_pnr_data_t data, int tsize, long timestamp);

/**
 * @brief process linein data in frame, at the same time, the preprocess is completed.
 * @param engine:    instance that create by create_aibs_engine
 * @param data:        contain input and output data
 * @param tsize:       the time length of the input data 
 * @param timestamp:   the time stampl of the input data
 * @return if success, return 0, or if failed, return err code;
 **/
int process_linein_data(void *engine, aibs_pnr_data_t data, int tsize, long timestamp);

/*
 * @brief free engine resource
 * @param engine: engine instace
 * @return if success, return 0, or if failed, return err code;
 */
int free_pnr_engine(void* engine);

/*
 * @brief free engine resource
 * @param engine: engine instace
 * @return if success, return 0, or if failed, return err code;
 */
int free_linein_pnr_engine(void* engine);

/*
 * @brief set work mode
 * @param engine: engine instance
 * @param mode: PNR_WORK_MODE
 * @param sample_rate: voice sample_rate
 * @return if avaliable return 0, or else return err code
 */
int set_pnr_work_mode(void * engine, PNR_WORK_MODE mode, int sample_rate);

/*
 * @brief set work mode
 * @param engine: engine instance
 * @param mode: PNR_WORK_MODE
 * @param sample_rate: voice sample_rate
 * @param frequency_spectrum: voice frequency_spectrum
 * @return if avaliable return 0, or else return err code
 */
int set_linein_pnr_work_mode(void * engine, PNR_WORK_MODE mode, int sample_rate, int spectrum);

/*
 * @brief set work mode
 * @param engine: engine instance
 * @param mode: PNR_WORK_MODE
 * @param sample_rate: voice sample_rate
 * @return if avaliable return 0, or else return err code
 */
int set_pnr_param(void * engine, short*vec);

/*
 * @brief Used to set the mute function for the MIC
 * @param engine: engine instace
 * @param option: if true, then the mic is muted
 * @return if success, return 0, or if failed, return err code;
 */
int set_pnr_mic_mute_option(void* engine, bool option);

/*
 * @brief Used to set the pnr enabled
 * @param engine: engine instace
 * @param option: if true, then the pnr is enable; else , the pnr is disabled
 * @return if success, return 0, or if failed, return err code;
 */
int set_pnr_enable_option(void* engine, bool option);

/*
 * @brief Used to set the audio quality for the output
 * @param engine: engine instace
 * @param quality: the auido quality
 * @return if success, return 0, or if failed, return err code;
 */
int set_pnr_audio_quality(void *engine, unsigned short quality);

/*
 * @brief get the version of engine resource
 * @param engine: engine instace
 * @return if success, return the version, or if failed, return NULL;
 */
const char* get_pnr_version(void *engine);

/*
 * @brief get HFT parameter of the  engine resource
 * @param engine: engine instace
 * @return if success, return HFT parameters, or if failed, return NULL;
*/
const char* get_pnr_HFT_param(void *engine);

/*
 * @brief get MVR parameter of the  engine resource
 * @param engine: engine instace
 * @return if success, return MVR parameters, or if failed, return NULL;
*/
const char* get_pnr_MVR_param(void *engine);

/*
 * @brief get Gen parameter of the  engine resource
 * @param engine: engine instace
 * @return if success, return Gen parameters, or if failed, return NULL;
*/
const char* get_pnr_Gen_param(void *engine);

/*
 * @brief get frame size of the engine
 * @param engine: engine instace
 * @return if success, return frameSize(ms) at the workMode and sampleRate;
*/
int get_pnr_frame_size(void *engine);

/*
 * @brief get frame size of the engine
 * @param engine: engine instace
 * @return if success, return frameSize(ms) at the workMode and sampleRate;
*/
int get_linein_pnr_frame_size(void *engine);

#ifdef __cplusplus
};
#endif

#endif
